<?php
/**
 * This class defines some build-in validators.
 * @see test.php to learn how to use it.
 * @author hikui
 * @version 0.1
 * @access public
 */
class ImbaValidator
{

    private static $builtInValidators = array(
        'email' => 'EmailValidator',//valid email check
        'url' => 'UrlValidator',//valid url check
        'numerical' => 'NumberValidator',//numbers only check
        'minlen' => 'MinLenValidator',//min length check
        'maxlen' => 'MaxLenValidator',//max length check
        'date' => 'DateValidator',//date check
        'between' => 'BetweenValidator', //range check
        'extension' => 'ExtensionValidator',//extension check
        'custom'=>'CustomValidator'//user custom validator
    );

    /**
     * The main function
     * @param String $VName validator name
     * @param String $Param string value to check
     * @param Mixed $Extra some extra rules that must be used in some func
     * @return <type>
     */
    public static function Validate($VName, $Param, $Extra=null)
    {
        if (is_string($VName) && is_string($Param))
        {
            if (isset(self::$builtInValidators[$VName]))
            {
                $functionName = self::$builtInValidators[$VName];
                $valid = self::$functionName($Param,$Extra);
                return $valid;
            } else
            {
                //throw new Exception;
            }
        }
    }

    /**
     * To check if the email address is valid
     * @param String $Param
     * @param Mixed $Extra no use in this function
     * @return Boolean success
     */
    private static function EmailValidator($Param,$Extra = null)
    {
        /**
         * @var string the regular expression used to validate the attribute value.
         * @see http://www.regular-expressions.info/email.html
         */
        $pattern = '/^[a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&\'*+\\/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$/';
        if(preg_match($pattern, $Param))
        {
            return true;
        }
        else
            return false;
    }

    /**
     * To check if the URL is valid
     * @param String $Param
     * @param Mixed $Extra no use in this function
     * @return Boolean success
     */
    private static function UrlValidator($Param,$Extra = null)
    {
        $pattern = '/^(http|https):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)/i';
        if(preg_match($pattern, $Param))
        {
            return true;
        }
        else
            return false;
    }

    /**
     * To check if string length is larger than min length
     * @param String $Param
     * @param Integer $MinLen MinLength
     * @return Boolean success
     */
    private static function MinLenValidator($Param, $MinLen)
    {
        $length = mb_strlen($Param);
        return ($length >= $MinLen);
    }

    /**
     * To check if string length is shorter than max length
     * @param String $Param
     * @param Integer $MaxLen
     * @return Boolean
     */
    private static function MaxLenValidator($Param, $MaxLen)
    {
        $length = mb_strlen($Param);
        return ($length <= $MaxLen);
    }

    /**
     * To check if Date String is valid
     * @param String $Param Date string to be checked
     * @param String $Format date format like 'ymd','mdy' etc.
     * @return Boolean
     */
    private static function DateValidator($Param, $Format=null)
    {
        $regex['dmy'] = '%^(?:(?:31(\\/|-|\\.|\\x20)(?:0?[13578]|1[02]))\\1|(?:(?:29|30)(\\/|-|\\.|\\x20)(?:0?[1,3-9]|1[0-2])\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:29(\\/|-|\\.|\\x20)0?2\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\\d|2[0-8])(\\/|-|\\.|\\x20)(?:(?:0?[1-9])|(?:1[0-2]))\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$%';
        $regex['mdy'] = '%^(?:(?:(?:0?[13578]|1[02])(\\/|-|\\.|\\x20)31)\\1|(?:(?:0?[13-9]|1[0-2])(\\/|-|\\.|\\x20)(?:29|30)\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:0?2(\\/|-|\\.|\\x20)29\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\\/|-|\\.|\\x20)(?:0?[1-9]|1\\d|2[0-8])\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$%';
        $regex['ymd'] = '%^(?:(?:(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(\\/|-|\\.|\\x20)(?:0?2\\1(?:29)))|(?:(?:(?:1[6-9]|[2-9]\\d)?\\d{2})(\\/|-|\\.|\\x20)(?:(?:(?:0?[13578]|1[02])\\2(?:31))|(?:(?:0?[1,3-9]|1[0-2])\\2(29|30))|(?:(?:0?[1-9])|(?:1[0-2]))\\2(?:0?[1-9]|1\\d|2[0-8]))))$%';
        $regex['dMy'] = '/^((31(?!\\ (Feb(ruary)?|Apr(il)?|June?|(Sep(?=\\b|t)t?|Nov)(ember)?)))|((30|29)(?!\\ Feb(ruary)?))|(29(?=\\ Feb(ruary)?\\ (((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))|(0?[1-9])|1\\d|2[0-8])\\ (Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep(?=\\b|t)t?|Nov|Dec)(ember)?)\\ ((1[6-9]|[2-9]\\d)\\d{2})$/';
        $regex['Mdy'] = '/^(?:(((Jan(uary)?|Ma(r(ch)?|y)|Jul(y)?|Aug(ust)?|Oct(ober)?|Dec(ember)?)\\ 31)|((Jan(uary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sept|Nov|Dec)(ember)?)\\ (0?[1-9]|([12]\\d)|30))|(Feb(ruary)?\\ (0?[1-9]|1\\d|2[0-8]|(29(?=,?\\ ((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))))\\,?\\ ((1[6-9]|[2-9]\\d)\\d{2}))$/';
        $regex['My'] = '%^(Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep(?=\\b|t)t?|Nov|Dec)(ember)?)[ /]((1[6-9]|[2-9]\\d)\\d{2})$%';
        $regex['my'] = '%^(((0[123456789]|10|11|12)([- /.])(([1][9][0-9][0-9])|([2][0-9][0-9][0-9]))))$%';
        if($Format==null)$Format='ymd';
        $pattern = $regex[$Format];
        if(preg_match($pattern, $Param))
        {
            return true;
        }
        else
            return false;
    }

    /**
     * To check the string length is in the range
     * @param <String> $Param
     * @param <Array> $Range
     * @return <Boolean>
     */
    private static function BetweenValidator($Param, $Range=null)
    {
        if (is_array($Range))
        {
            //print_r($Range);
            $min = $Range[0];
            $max = $Range[1];
            $length = mb_strlen($Param);
            return ($length >= $min && $length <= $max);
        }
        return false;
    }

    /**
     * To check if param is match the allowed extensions.
     * @param <String> $Param
     * @param <Array> $Extensions Extension array like: array('jpg','png','gif')
     * @return <Boolean>
     */
    private static function ExtensionValidator($Param, $Extensions=null)
    {
        if (is_array($Extensions))
        {
            $extension = strtolower(array_pop(explode('.', $Param)));
            foreach ($Extensions as $value)
            {
                if ($extension == strtolower($value))
                {
                    return true;
                }
            }
            return false;
        }
        return false;
    }

    /**
     * To check the string is numbers only
     * @param String $Param
     * @param Mixed $Extra no use in this function
     * @return Boolean success
     */
    private static function NumberValidator($Param,$Extra = null)
    {
        return is_numeric($Param);
    }

    /**
     * User custom
     * @param String $Param
     * @param String $Regex
     * @return Boolean success
     */
    private static function CustomValidator($Param,$Regex)
    {
        if(preg_match($Regex, $Param))
        {
            return true;
        }
        else
            return false;
    }
}

?>
